﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TimeTravel.XnaLibrary.GamePlay
{
	/// <summary>
	/// Represents the history of turns in the Time Travel game
	/// </summary>
	public class TurnHistory
	{
		private int mCurrentTurn = 1;
		private List<MapState> mTurnsPassed;
		private AI mBot1;
		private AI mBot2;
		private List<UpgradeBoost> mBoosts;
		
		/// <summary>
		/// Gets the current 1-based index of the current turn.
		/// </summary>
		public int CurrentTurn
		{
			get { return mCurrentTurn; }
		}

		/// <summary>
		/// Gets the current state of the first bot.
		/// </summary>
		public AI Bot1
		{
			get { return mBot1; }
		}
		
		/// <summary>
		/// Gets the current state of the second bot.
		/// </summary>
		public AI Bot2
		{
			get { return mBot2; }
		}

		/// <summary>
		/// Gets a list of the currently available boosts throughtout the map
		/// </summary>
		public List<UpgradeBoost> Boosts
		{
			get { return mBoosts; }
		}

		/// <summary>
		/// Initializes a new TurnHistory instance with the specified starting states.
		/// </summary>
		/// <param name="bot1StartingState">The starting state of the first bot.</param>
		/// <param name="bot2StartingState">The starting state of the second bot.</param>
		public TurnHistory(AI bot1StartingState, AI bot2StartingState)
		{
			mBot1 = bot1StartingState;
			mBot2 = bot2StartingState;
			mBoosts = new List<UpgradeBoost>();
			mTurnsPassed = new List<MapState>();
			mTurnsPassed.Add(new MapState());
		}

		/// <summary>
		/// Sends a unit from one turn to another (keeps the original copy).
		/// </summary>
		/// <param name="unit">The unit to be transported.</param>
		/// <param name="playerOwnerIndex">The index of the player owning the unit.</param>
		/// <param name="turnTo">The turn to send the unit to.</param>
		public void SendUnitInTime(Unit unit, int playerOwnerIndex, int turnTo)
		{
			if (playerOwnerIndex != 1 && playerOwnerIndex != 2)
				throw new ArgumentException("Player owner index must be either 1 or 2");

			AI unitOwner = playerOwnerIndex == 1 ? mTurnsPassed[turnTo].Bot1 : mTurnsPassed[turnTo].Bot2;
			unitOwner.ActiveUnits.Add(unit);
		}

		/// <summary>
		/// Kills a unit in the specified turn.
		/// </summary>
		/// <param name="unit">The unit to be killed.</param>
		/// <param name="playerOwnerIndex">The index of the player owning the unit.</param>
		/// <param name="turn">The turn in which the unit should be killed.</param>
		public void KillUnit(Unit unit, int playerOwnerIndex, int turn)
		{
			if (playerOwnerIndex != 1 && playerOwnerIndex != 2)
				throw new ArgumentException("The index of the unit`s owner player must be either 1 or two");

			AI playerOwner = playerOwnerIndex == 1 ? mTurnsPassed[turn].Bot1 : mTurnsPassed[turn].Bot2;
			playerOwner.ActiveUnits.Remove(unit);
		}

		/// <summary>
		/// Saves the current state.
		/// </summary>
		public void SaveState()
		{
			AI bot1State = new AI(mBot1);
			AI bot2State = new AI(mBot2);
			mTurnsPassed.Add(new MapState(bot1State, bot2State, new List<UpgradeBoost>(mBoosts)));
			mCurrentTurn++;
		}

		/// <summary>
		/// Restores the game state to the one previously saved in the specified turn.
		/// </summary>
		/// <param name="turn">The turn to restore the state to.</param>
		public void RestoreState(int turn)
		{
			mBot1 = new AI(mTurnsPassed[turn].Bot1);
			mBot2 = new AI(mTurnsPassed[turn].Bot2);
			mBot1.Enemy = mBot2;
			mBot2.Enemy = mBot1;
			mBoosts = new List<UpgradeBoost>(mTurnsPassed[turn].Boosts);
			mCurrentTurn = turn + 1;
			mTurnsPassed.RemoveRange(mCurrentTurn, mTurnsPassed.Count - mCurrentTurn);
		}
	}
}
